#ifndef GAMEMATHHEADER
#define GAMEMATHHEADER
#include "GE_Base.h"
namespace Syp
{
#define PI 3.14159265f

	struct Quat;
	///Quaternion
	typedef Quat AngleAxis;
	///A Basic Quaternion class
	struct SYPAPI Quat
	{
		Quat();
		Quat(float X, float Y, float Z, float W):x(X),y(Y),z(Z),w(W)
		{
		};
		Quat operator*(const Quat& b);
		Quat operator+(const Quat& b);
		Quat operator*(const float& b);
		void Normalize();
		void axisNormalize();
		AngleAxis convertToAngleAxis();
		///Converts values to a quaternion. Existing values are assumed to be an angle-axis with the angle in degrees.
		Quat convertToQuat();

		float x;
		float y;
		float z;
		float w;
	};

	struct SYPAPI Point3 
	{
		Point3(float X,float Y,float Z):x(X),y(Y),z(Z)
		{
		};
		Point3(): x(0.0f),y(0.0f),z(0.0f)
		{
		};
		bool operator==(const Point3& b);
		Point3 operator*(const float& b);
		Point3 operator-(const Point3& b);
		Point3 operator+(const Point3& b);
		void Normalize();
		float x;
		float y;
		float z;
	};

	struct SYPAPI Point4:public Point3
	{
		Point4():w(1.0f)
		{
		};
		Point4(float X,float Y,float Z,float W):Point3(X,Y,Z),w(W)
		{
		};
		float w;
	};

	///Math class containing useful Math functions.
	class SYPAPI Math
	{
	public:
		//Converts angleAxis to a 4X4 Matrix
		static void getMatrix(AngleAxis& a, float* matrix);
		///Interpolates 2 Quaternions based on interpolation value(time). time has a range of 0.0f to 1.0f
		static void InterpolateQuat(Quat& first,Quat& second,Quat& result,float time);
		///Interpolates 2 Point3s based on interpolation value(time). time has a range of 0.0f to 1.0f
		static void InterpolatePoint3(Point3& first, Point3& second, Point3& result, float time);
		static void QuatToMatrix(Quat& q,float* mat);
		///Sets a matrix to identity
		static void IdentityMatrix(float* mat);

		static void MaxToGLMatrix(float* max, float* gl);
		static int nextPowerOf2 (int a );
		///Inverse a matrix
		static void InverseMatrix(float *mat, float *dst);

		static void TransposeMatrix(float* mat);
		static void multMat(float* A,float* B,float* P);
		static void MultVectorByMatrix(float* m, float* v,float weight, float* result);
		///Difference is that in this function, 4th row of matrix values are ignored thus making it slightly faster for normals
		static void MultNormalByMatrix(float* m, float* v, float weight,float* result);
		//Inverses the Quaternion
		static void InverseQuat(Quat &q);
		static void NormalizePlane(Point4& plane);


	};
}

#endif

